// Copyright (c) 2012-2013, Jordi Corbilla
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// - Neither the name of this library nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

unit Testthundax.COMLib;
{

  Delphi DUnit Test Case
  ----------------------
  This unit contains a skeleton test case class generated by the Test Case Wizard.
  Modify the generated code to correctly setup and call the methods from the unit
  being tested.

}

interface

uses
  TestFramework, ComObj, thundax.COMLib.contract, Windows, ActiveX;

type
  TRegProcFunc = function: HResult; stdcall;

  TestTCOMLib = class(TTestCase)
  strict private
    FCOMLib: ICOMLib;
  private
    procedure RegisterDLL;
    function ExecuteProcess(const ExecuteFile, ParamString: string): boolean;
  public
    procedure SetUp; override;
    procedure TearDown; override;
  published
    procedure TestExecute;
  end;

implementation

uses
  SysUtils, Classes, Forms, ShellAPI;

function TestTCOMLib.ExecuteProcess(const ExecuteFile, ParamString: string): boolean;
var
  SEInfo: TShellExecuteInfo;
  ExitCode: DWORD;
begin
  FillChar(SEInfo, SizeOf(SEInfo), 0);
  SEInfo.cbSize := SizeOf(TShellExecuteInfo);

  SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  SEInfo.Wnd := Application.Handle;
  SEInfo.lpFile := PChar(ExecuteFile);
  SEInfo.lpParameters := PChar(ParamString);
  SEInfo.nShow := SW_HIDE;

  Result := False;
  if ShellExecuteEx(@SEInfo) then
  begin
    repeat
      Application.ProcessMessages;
      GetExitCodeProcess(SEInfo.hProcess, ExitCode);
    until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
    Result := True;
  end;
end;

procedure TestTCOMLib.RegisterDLL;
var
  AProcRegFunc: TRegProcFunc;
  handle: THandle;
  dllPath: string;
begin
  try
    dllPath := ExtractFilePath(Application.ExeName) + 'thundax.COMLib.dll';
    handle := LoadLibrary(PChar(dllPath));
    if handle <> 0 then
    begin
      AProcRegFunc := GetProcAddress(handle, 'DllRegisterServer');
      if Assigned(AProcRegFunc) then
        ExecuteProcess('regsvr32', '/s ' + dllPath);
      FreeLibrary(handle);
    end;
  except
  end;
end;

procedure TestTCOMLib.SetUp;
begin
  OleCheck(CoCreateInstance(Class_COMLib, nil, CLSCTX_ALL, ICOMLib, FCOMLib));
end;

procedure TestTCOMLib.TearDown;
begin
  FCOMLib := nil;
end;

procedure TestTCOMLib.TestExecute;
var
  ReturnValue: string;
  param: string;
begin
  RegisterDLL;
  param := 'Test';
  ReturnValue := FCOMLib.Execute(param);
  CheckTrue(ReturnValue = 'TCOMLibExample Executed with param: Test', 'Invalid response from the COM Object');
end;

initialization

// Register any test cases with the test runner
RegisterTest(TestTCOMLib.Suite);

end.
